package top.gytf.unifiedcall.producer.support.wrap;

import cn.hutool.core.collection.CollUtil;
import top.gytf.unifiedcall.common.support.UnifiedCallApiContract;
import top.gytf.unifiedcall.model.code.StatusCode;
import top.gytf.unifiedcall.model.code.builtin.BuiltinStatusCode;
import top.gytf.unifiedcall.model.response.UnifiedResponse;
import top.gytf.unifiedcall.common.api.ApiDefinition;
import top.gytf.unifiedcall.producer.response.ResponseHandler;
import top.gytf.unifiedcall.producer.response.ResponseHandlerContext;

import java.util.Optional;

import static top.gytf.unifiedcall.producer.constant.ResponseHandlerParameterConstants.WRAP_UNIFIED_RESPONSE_PARAMETER;

/**
 * 包装为统一响应的处理器
 */
public class WrapUnifiedResponseHandler implements ResponseHandler {
    public static final int POSITION = Integer.MAX_VALUE - 100;

    @Override
    public int order() {
        return POSITION;
    }

    @Override
    public boolean isSupported(ApiDefinition apiDefinition) {
        return CollUtil.isNotEmpty(apiDefinition.getApiContracts(UnifiedCallApiContract.class));
    }

    @Override
    public void handle(ResponseHandlerContext context) {
        Object response = context.getResponse();

        boolean isCustomizedResponse = context.getApiDefinition().getApiContracts(UnifiedCallApiContract.class).stream()
                .anyMatch(UnifiedCallApiContract::isCustomizedResponse);
        // 进行包装
        WrapUnifiedResponseParameter parameter = context.getParameter(WRAP_UNIFIED_RESPONSE_PARAMETER, WrapUnifiedResponseParameter.class);
        if (!isCustomizedResponse || parameter != null) {
            if (parameter == null) {
                parameter = context.computeParameterIfAbsent(WRAP_UNIFIED_RESPONSE_PARAMETER, WrapUnifiedResponseParameter.class, WrapUnifiedResponseParameter::new);
            }
            StatusCode code = parameter.getCode();
            if (code == null) {
                // 处理默认的状态
                code = BuiltinStatusCode.SUCCESS;
                parameter.setCode(code);
            }
            response = UnifiedResponse.with(code, Optional.ofNullable(parameter.getMessage()).orElse(code.message()), response);
        }

        context.complete(response);
    }
}
